package insight.google.game.era.bo.policy;

import insight.google.game.era.bo.GameActionLog;
import insight.google.game.era.bo.GameRoom;
import insight.google.game.era.bo.GameUser;
import insight.google.game.era.bo.Task;
import insight.google.game.era.bo.card.CharacterCard;
import insight.google.game.era.bo.policy.character.CharacterPolicy;
import insight.google.game.era.client.proxy.PlayerClientProxy;
import insight.google.game.era.client.proxy.PlayerClientProxyImpl;
import insight.google.game.era.core.cache.AppCacheManager;
import insight.google.game.era.core.cache.PendingEventCacheManager;
import insight.google.game.era.core.cache.PolicyTaskListCacheManager;
import insight.google.game.era.core.hub.HubServiceManager;
import insight.google.game.era.core.hub.PendingEvents;
import insight.google.game.era.core.hub.UserEvents;
import insight.google.game.era.data.policys.Policy;
import insight.google.game.era.mgr.GameLogManager;
import insight.google.game.era.service.RoomServiceImpl;



import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



public class PolicyCenter{
    
    /**
	 * 
	 */

	protected static PolicyCenter policyCenter;
	
	/** common definition */
	//character card policy definition
	public static final int POLICY_CHARACTER_CARD_CAOCAO_JIANXIOING = 20010;
	public static final int POLICY_CHARACTER_CARD_CAOCAO_HUJIA = 20011;
	public static final int POLICY_CHARACTER_CARD_LIUBEI_RENDE = 20020;
	public static final int POLICY_CHARACTER_CARD_SUNQUAN_ZHIHENG = 20030;
	public static final int POLICY_CHARACTER_CARD_ZHANGFEI_PAOXIAO = 20040;
	public static final int POLICY_CHARACTER_CARD_ZHOUYU_YINZI = 20050;
	public static final int POLICY_CHARACTER_CARD_GUOJIA_YIJI = 20060;
	public static final int POLICY_CHARACTER_CARD_ZHAOYUN_LONGDAN = 20070;
	public static final int POLICY_CHARACTER_CARD_HUANGGAI_KUROU = 20080;
	
	//game card policy definition
	public static final int POLICY_GAME_CARD_ATTACK = 1001;
	public static final int POLICY_GAME_CARD_DEFEND = 1002;
	public static final int POLICY_GAME_CARD_MILK = 1003;
	//equipment card policy definition
	public static final int POLICY_GAME_CARD_WEAPON = 1004;
	public static final int POLICY_GAME_CARD_ATTACKHORSE = 1005;
	public static final int POLICY_GAME_CARD_DEFENDHORSE = 1006;
	public static final int POLICY_GAME_CARD_YINYANGSHIELD = 1007;
	//
	public static final int POLICY_GAME_CARD_DUEL = 1008;
	public static final int POLICY_GAME_CARD_FEI = 1009;
	public static final int POLICY_GAME_CARD_PG = 1010;
	
	

    private Map policyMatch = new HashMap();
    private List<Map> taskList = new ArrayList<Map>();
    
    public final static String KEY_METHOD = "method";
    public final static String KEY_PLACE = "place";
    public final static String KEY_PARAMS = "params";
    public final static String CARD_TYPE_ATTACK = "attack";
    public final static String CARD_TYPE_DEFEND = "defend";
    public final static String CARD_TYPE_MILK = "milk";
    public final static String CARD_TYPE_DUEL = "duel";
    public final static String CARD_TYPE_FOREIGN_ENEMY_INVASIO = "foreign_enemy_invasio";
    public final static String CARD_TYPE_LIU_BEI_JIJIANG = "liubei_jijiang";
    
    //task key
    public final static String KEY_ORIGINAL = "original";
    public final static String KEY_TARGET = "target";
    public final static String KEY_ORIGINAL_CARD = "originalCard";
    public final static String KEY_MATCH_VALUE = "matchValue";
    
    private PlayerClientProxy playerClientProxy;
    
//    private Cache cache = null;
    private PolicyTaskListCacheManager policyTaskListCacheManager = new PolicyTaskListCacheManager();

    PolicyCenter(){
        intilize();
    }
    
    public static PolicyCenter getInstance(){
        if(policyCenter == null){
            policyCenter = new PolicyCenter();
        }
        return policyCenter;
    }
    
    private void intilize(){
        String[] attackParam = {"String"};
        Map matchValue = new HashMap();
        matchValue.put(KEY_METHOD, "doMatchCard");
        matchValue.put(KEY_PLACE, "client");
        policyMatch.put(CARD_TYPE_ATTACK, matchValue);
        policyMatch.put(CARD_TYPE_DUEL, matchValue);
        policyMatch.put(CARD_TYPE_FOREIGN_ENEMY_INVASIO, matchValue);

        Map milkMatchValue = new HashMap();
        milkMatchValue.put(KEY_METHOD, "healLife");
        milkMatchValue.put(KEY_PLACE, "client");
        policyMatch.put(CARD_TYPE_MILK, milkMatchValue);
        
        Map askTypeMatchValue = new HashMap();
        askTypeMatchValue.put(KEY_METHOD, "askCardDiscard");
        askTypeMatchValue.put(KEY_PLACE, "client");
        policyMatch.put(CARD_TYPE_LIU_BEI_JIJIANG, askTypeMatchValue);
        

        playerClientProxy = PlayerClientProxyImpl.getInstance();
//        cache = AppCacheManager.getInstance().getCache();
    }
    
    public Map getPolicyDataMap(String cardName){
        return (Map)policyMatch.get(cardName);
    }
    
//    public void putTask(GameUser orgUser, GameUser trgUser, String originalCard, String matchValue){
//        Map taskMap = new HashMap();
//        taskMap.put(KEY_ORIGINAL, orgUser);
//        taskMap.put(KEY_TARGET, trgUser);
//        taskMap.put(KEY_ORIGINAL_CARD, originalCard);
//        
//        taskMap.put(KEY_MATCH_VALUE, matchValue);
//        taskList.add(taskMap);
////        policyTaskListCacheManager.updateToCache(taskList);
////        cache.put("tasklist", taskList);
//    }
//    
//    public void removeTask(int index){
//        if(taskList.size() > index){
//            taskList.remove(index);
//            policyTaskListCacheManager.updateToCache(taskList);
////            cache.put("tasklist", taskList);
//        }
//    }
//    
//    public List<Map> getTaskList(){
//    	List<Map> cacheTaskList = policyTaskListCacheManager.getAllFromCache();
//    	if(cacheTaskList != null) this.taskList = cacheTaskList;
//        return taskList;
//    }
    
    public boolean executeCardPolicy(List<Integer> cardPolicy, GameUser fromUser, GameUser[] toUser, Map params){
        //set original user active to false for wait other user output relative card.
        String jsComponentId = (String)params.get("jsComponenetId");
        //remove client user card
//        playerClientProxy.removeClientCard(fromUser.getScriptProxy(), jsComponentId);
        if(fromUser.getScriptProxy() != null){
			PlayerClientProxyImpl.getInstance().removeClientCard(fromUser.getScriptProxy(), jsComponentId);
		}
        
        //set active false
//        playerClientProxy.setActive(fromUser.getScriptProxy(), jsComponentId, false);
        fromUser.setClientActive(false, jsComponentId);
        //execute card policy
        for(int policyId : cardPolicy){
			Policy policy = PolicyFactory.getInstance(policyId);
            ((AbstractPolicy) policy).execute(fromUser, toUser, params);
//            ((GameRoom)fromUser.getCurrentRoom()).getGameLogManager().broadcastGameActionLog();
        }
        return false;
    }
    
    public void removeUserTask(String userName){
        for(Map task : taskList){
            String trgUser = (String)task.get(PolicyCenter.KEY_TARGET);
            if(trgUser.equals(userName)){
                taskList.remove(task);
            }
        }
//        cache.put("tasklist", taskList);
    }
    
    public boolean failToMatchCard(GameUser failUser, GameRoom room, Map params){
        String jsComponentId = (String)params.get("jsComponenetId");
        //set fail user active to false
//        playerClientProxy.setActive(failUser.getScriptProxy(), jsComponenetId, false);
        failUser.setClientActive(false, jsComponentId);
        
        boolean saveDyingUserFail = false;

        //GameUser orgUser = null;
        //remove relative card
        String originalCard = "";
        int index = 0;
        
        GameLogManager gameLogManager = room.getGameLogManager();
        gameLogManager.addGameLog(new GameActionLog(failUser.getName() + " is failed to play defend card, so he lost one point blood!"));
        
        //user is dying, then user be dead.
        if(failUser.getState() == GameUser.STATE_DYING){
        	//remove task
			List<Task> tasklist = room.getTaskList();
			try{  
			for(Task task : tasklist){
			    String matchValue = task.getMatchCardValue();
			    String trgUser = task.getTargetUserName();
			    if(trgUser.equals(failUser.getName())){
			    	//orgUser = task.getOrgUserName()
			    	room.removeTask(index);
			    	saveDyingUserFail = true;
//			    	(new RoomServiceImpl()).quitRoom(true);
			        break;
			    }
			    index++;
			}
			}catch(Exception e){
				e.printStackTrace();
			}
			
			
			//set User dead
			failUser.setState(GameUser.STATE_DEAD);

        }
        else{
            //heal user life
//          playerClientProxy.healLife(failUser.getScriptProxy(), jsComponenetId, -1);
			failUser.addBlood(-1,jsComponentId);
			if(failUser.removeBloodAndCheckDead(1, jsComponentId)){
				//user is dying, now is asking
				return saveDyingUserFail;
			}
          //notify others
          //room.notifyUserLife(failUser, false);
          
          //check fail user character policy
			CharacterCard curCharacter = failUser.getCharacterCard();
	  		HashMap policyPara = new HashMap();
	  		policyPara.put("jsComponenetId", jsComponentId);
	  		policyPara.put("hurtCard", originalCard);
	  		//execute selected policy
	  		List<Integer> chaPolicy = curCharacter.getPolicyList();
	  		int type = 0;
	  		for(Integer policyId : chaPolicy){
	  			Policy policy = PolicyFactory.getInstance(policyId);
	  			if(policy instanceof CharacterPolicy){
	  				type = ((CharacterPolicy)policy).getType();
	  				if(type == CharacterPolicy.TYPE_BE_HURTED){
	  					GameUser[] users = new GameUser[1];
	  					users[0] = failUser; 
	  					((CharacterPolicy)policy).beHurtedExec(failUser, users, policyPara);
	  				}
	  			}
	  		}
	
	//        GameRoom  currentRoom = failUser.getCurrentRoom();
	//        List<Task> tasklist = currentRoom.getTaskList();
	        List<Task> tasklist = room.getTaskList();
	        
	        for(Task task : tasklist){
	            String matchValue = task.getMatchCardValue();
	            String trgUser = task.getTargetUserName();
	            if(trgUser.equals(failUser.getName())){
	            	//orgUser = task.getOrgUserName()
	                //originalCard = (String)task.getOrgCardId();
	                //orgUser = room.getUserByName(orignal);
	            	room.removeTask(index);
	                break;
	            }
	            index++;
	        }
	          
	          //add fail user user milk card premission
	          List<String> activeCards = failUser.getActiveCards();
	          activeCards.add("milk");
	          failUser.setActiveCards(activeCards,jsComponentId);
	//          playerClientProxy.setActiveCard(failUser.getScriptProxy(), jsComponentId, failUser.getActiveCards());
	          //set target user active
	//          playerClientProxy.setActive(orgUser.getScriptProxy(), jsComponentId, true);
	         //if(conf) != null)orgUser.setActive(true, jsComponentId);
        }
        return saveDyingUserFail;
    }

}
